#include "SearchOverlay.h"

#include <QApplication>
#include <QEasingCurve>
#include <QEvent>
#include <QFocusEvent>
#include <QGraphicsDropShadowEffect>
#include <QGuiApplication>
#include <QScreen>
#include <QVBoxLayout>

#include "DictEngin.h"

SearchOverlay::SearchOverlay(MdxEngin* dict, QWidget* parent)
    : QWidget(parent), m_dict(dict) {
    setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
    setAttribute(Qt::WA_TranslucentBackground);

    // Central container for rounded corners and shadow
    QWidget* container = new QWidget(this);
    container->setObjectName("container");
    QVBoxLayout* root = new QVBoxLayout(this);
    root->setContentsMargins(0, 0, 0, 0);
    root->addWidget(container);

    QVBoxLayout* v = new QVBoxLayout(container);
    // v->setContentsMargins(20, 20, 20, 20);
    // v->setSpacing(10);

    m_input = new QLineEdit(container);
    m_input->setPlaceholderText(QString::fromUtf8("输入单词…"));
    m_input->setClearButtonEnabled(true);
    v->addWidget(m_input);

    m_list = new QListWidget(container);
    m_list->setVisible(false);
    m_list->setUniformItemSizes(true);
    m_list->setMaximumHeight(200);
    v->addWidget(m_list);

    // Shadow effect
    // auto* shadow = new QGraphicsDropShadowEffect(container);
    // shadow->setBlurRadius(24);
    // shadow->setOffset(0, 8);
    // shadow->setColor(QColor(0, 0, 0, 80));
    // container->setGraphicsEffect(shadow);

    // applyStyle();

    // Animation
    m_anim = new QPropertyAnimation(this, "geometry", this);
    m_anim->setDuration(280);
    m_anim->setEasingCurve(QEasingCurve::OutCubic);

    // Signals
    connect(m_input, &QLineEdit::textChanged, this,
            &SearchOverlay::onTextChanged);
    connect(m_list, &QListWidget::itemActivated, this,
            &SearchOverlay::onItemActivated);

    // Enter key submits
    connect(m_input, &QLineEdit::returnPressed, this, [this]() {
        emit searchSubmitted(m_input->text());
        hideWithSlide();
    });
}

void SearchOverlay::applyStyle() {
    setStyleSheet(
        "#container{"
        "background:white;"
        "border-radius:16px;"
        "}"
        "QLineEdit{"
        "font-size:18px;"
        "padding:8px 12px;"
        "border:1px solid #D0D7DE;"
        "border-radius:10px;"
        "}"
        "QLineEdit:focus{"
        "border:1px solid #4C9AFF;"
        "}"
        "QListWidget{"
        "border:1px solid #E3E8EF;"
        "border-radius:10px;"
        "}"
        "QListWidget::item{"
        "padding:6px;"
        "}"
        "QListWidget::item:selected{"
        "background:#E6F0FF;"
        "}");
}

QRect SearchOverlay::targetGeometry() const {
    QScreen* s = QGuiApplication::primaryScreen();
    QRect sg = s ? s->geometry() : QRect(0, 0, 1280, 800);
    int w = qMin(800, sg.width() - 80);
    int h = 300 + (m_list->isVisible()
                       ? qMin(200, m_list->sizeHintForRow(0) * 6 + 20)
                       : 0);
    int x = sg.x() + (sg.width() - w) / 2;
    int y = sg.y() + 20;  // drop from very top to 20px margin
    return QRect(x, y, w, h);
}

void SearchOverlay::toggle() {
    if (isVisible()) {
        hideWithSlide();
    } else {
        showWithSlide();
    }
}

void SearchOverlay::showWithSlide() {
    m_showing = true;
    QRect end = targetGeometry();
    QRect start(end.x(), end.y() - end.height() - 40, end.width(),
                end.height());
    setGeometry(start);
    show();
    raise();
    m_input->setFocus();
    m_input->selectAll();
    m_anim->stop();
    m_anim->setStartValue(start);
    m_anim->setEndValue(end);
    m_anim->start();
    activateWindow();
    m_gap.start();
}

void SearchOverlay::hideWithSlide() {
    if (!m_showing) return;
    m_showing = false;
    hide();
    QRect start = geometry();
    QRect end(start.x(), start.y() - start.height() - 40, start.width(),
              start.height());
    m_anim->stop();
    // m_anim->setStartValue(start);
    // m_anim->setEndValue(end);
    // m_anim->start();
    // connect(m_anim, &QPropertyAnimation::finished, this,
    //         [this]() { this->hide(); });
}

void SearchOverlay::focusOutEvent(QFocusEvent* e) {
    QWidget::focusOutEvent(e);
    hideWithSlide();
}

bool SearchOverlay::event(QEvent* e) {
    if (e->type() == QEvent::WindowDeactivate) {
        if (!(m_gap.elapsed() < 500)) {
            hideWithSlide();
        }
    }
    return QWidget::event(e);
}

void SearchOverlay::onTextChanged(const QString& text) {
    m_list->clear();
    if (!m_dict || text.trimmed().isEmpty()) {
        m_list->setVisible(false);
        // Adjust height when list hidden
        setGeometry(targetGeometry());
        return;
    }
    QStringList suggestions;
    // Use dictionary suggest to get candidates
    suggestions = m_dict->suggest(text);

    const int maxItems = 10;
    int count = 0;
    for (const QString& s : suggestions) {
        m_list->addItem(s);
        if (++count >= maxItems) break;
    }
    m_list->setVisible(m_list->count() > 0);
    setGeometry(targetGeometry());
}

void SearchOverlay::onItemActivated(QListWidgetItem* item) {
    if (!item) return;
    m_input->setText(item->text());
    emit searchSubmitted(item->text());
    hideWithSlide();
}
